﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Collections;

namespace CLFramework.Windows.Forms
{
    public class MdiTabCantainer : TabControl
    {
        #region Ctor.

        public MdiTabCantainer()
        {
            this.AllowDrop = true;
            this.Dock = DockStyle.Fill;
            this.MouseDoubleClick += new MouseEventHandler(FormTabCantainer_MouseDoubleClick);
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            this.ResumeLayout(false);
        }

        #endregion

        #region Members

        //private System.ComponentModel.IContainer components;

        private DateTime lastClick;

        #endregion

        #region Properties

        private bool enableDblClickClose = true;

        public bool EnableDblClickClose
        {
            get { return enableDblClickClose; }
            set { enableDblClickClose = value; }
        }

        #endregion

        #region Methods

        public void AddMdiForm(MdiUserControl uc)
        {
            if (uc == null)
                return;

            for (int i = 0; i < this.TabPages.Count; i++)
            {
                if (this.TabPages[i].Name == "tp_" + uc.Name)
                {
                    this.SelectedIndex = i;
                    return;
                }
            }

            TabPage tp = new TabPage(uc.Caption);

            tp.SuspendLayout();
            this.SuspendLayout();

            this.TabPages.Add(tp);

            tp.Controls.Add(uc);
            tp.Name = "tp_" + uc.Name;

            //add by lance 2011-10-25
            uc.MdiCantainer = this;

            uc.Dock = DockStyle.Fill;
            uc.Location = new System.Drawing.Point(3, 3);
            uc.Margin = new System.Windows.Forms.Padding(4, 4, 10, 4);
            uc.Size = new System.Drawing.Size(990, 667);

            tp.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

            uc.Onload();
            this.SelectedTab = tp;
        }

        public void SelectMdiForm(string ucName)
        {
            for (int i = 0; i < this.TabPages.Count; i++)
            {
                if (this.TabPages[i].Name == "tp_" + ucName)
                {
                    this.SelectedIndex = i;
                    return;
                }
            }
        }

        protected override void Dispose(bool disposing)
        {
            ModulesConfiguration.GetConfig().UnloadModules();
            base.Dispose(disposing);
        }

        #endregion

        #region Event Handlers

        void FormTabCantainer_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (!this.EnableDblClickClose)
            {
                return;
            }

            TabControl tab = (TabControl)sender;
            Point pt = new Point(e.X, e.Y);

            for (int i = 0; i < tab.TabCount; i++)
            {
                Rectangle recTab = tab.GetTabRect(i);
                if (recTab.Contains(pt))
                {
                    TabPage seltab = this.SelectedTab;
                    int seltabindex = this.SelectedIndex;

                    (seltab.Controls[0] as MdiUserControl).Unload();
                    seltab.Controls.Clear();
                    tab.Controls.Remove(seltab);
                    if (seltabindex >= 1)
                    {
                        tab.SelectTab(seltabindex - 1);
                    }

                    return;
                }
            }
        }

        #endregion

        #region Drag & Drop

        protected override void OnDragOver(System.Windows.Forms.DragEventArgs e)
        {
            base.OnDragOver(e);

            Point pt = new Point(e.X, e.Y);

            pt = PointToClient(pt);

            TabPage hover_tab = GetTabPageByTab(pt);

            if (hover_tab != null)
            {
                if (e.Data.GetDataPresent(typeof(TabPage)))
                {
                    e.Effect = DragDropEffects.Move;
                    TabPage drag_tab = (TabPage)e.Data.GetData(typeof(TabPage));
                    int item_drag_index = FindIndex(drag_tab);
                    int drop_location_index = FindIndex(hover_tab);
                    if (item_drag_index != drop_location_index)
                    {
                        ArrayList pages = new ArrayList();
                        for (int i = 0; i < TabPages.Count; i++)
                        {
                            if (i != item_drag_index)
                                pages.Add(TabPages[i]);
                        }
                        pages.Insert(drop_location_index, drag_tab);
                        TabPages.Clear();
                        TabPages.AddRange((TabPage[])pages.ToArray(typeof(TabPage)));
                        SelectedTab = drag_tab;
                    }
                }
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if ((DateTime.Now - lastClick).TotalMilliseconds < 300)
            {
                FormTabCantainer_MouseDoubleClick(this, e);
            }


            lastClick = DateTime.Now;

            Point pt = new Point(e.X, e.Y);
            TabPage tp = GetTabPageByTab(pt);

            if (tp != null)
            {
                DoDragDrop(tp, DragDropEffects.All);
            }
        }

        private TabPage GetTabPageByTab(Point pt)
        {
            TabPage tp = null;
            for (int i = 0; i < TabPages.Count; i++)
            {
                if (GetTabRect(i).Contains(pt))
                {
                    tp = TabPages[i];
                    break;
                }
            }
            return tp;
        }

        private int FindIndex(TabPage page)
        {
            for (int i = 0; i < TabPages.Count; i++)
            {
                if (TabPages[i] == page)
                    return i;
            }

            return -1;
        }

        #endregion
    }
}
